package com.inspur.cloud.service.dataspace;

import com.inspur.cloud.configuration.ApiConfig;
import com.inspur.cloud.dao.dataspace.*;
import com.inspur.cloud.entity.dataspace.*;
import com.inspur.cloud.entity.dataspace.common.EditUserParam;
import com.inspur.cloud.entity.dataspace.common.OpResult;
import com.inspur.cloud.entity.dataspace.common.UserAddParam;
import com.inspur.cloud.enums.RoleEnum;
import com.inspur.cloud.exception.ApiException;
import com.inspur.cloud.security.Base64PasswordEncoder;
import com.inspur.cloud.service.ambari.ComponentDesiredStateService;
import com.inspur.cloud.service.ambari.HostsService;
import com.inspur.cloud.util.TConstants;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
public class UserManagerService {

    private static final Logger logger = LoggerFactory.getLogger(UserManagerService.class);
    @Autowired
    private UserService userService;
    @Autowired
    private UserResRelationSerivce userResRelationSerivce;
    @Autowired
    private HdfsResourceService hdfsResourceService;
    @Autowired
    private HdfsManagerService hdfsManagerService;
    @Autowired
    private HiveManagerService hiveManagerService;
    @Autowired
    private HbaseManagerService hbaseManagerService;
    @Autowired
    private YarnManagerService yarnManagerService;
    @Autowired
    private KafkaManagerService kafkaManagerService;
    @Autowired
    private HbaseResourceService hbaseResourceService;
    @Autowired
    private HiveResourceService hiveResourceService;
    @Autowired
    private KafkaResourceService kafkaResourceService;
    @Autowired
    private YarnResourceService yarnResourceService;
    @Autowired
    Base64PasswordEncoder base64PasswordEncoder;
    @Autowired
    private KerberosService kerberosService;
    @Autowired
    private RangerService rangerService;
    @Autowired
    private LinuxService linuxService;
    @Autowired
    ClusterConfigUtil clusterConfigUtil;
    @Autowired
    private ComponentDesiredStateService componentDesiredStateService;

    public UserEntity findByName(String name) {
        return userService.findUserByName(name);
    }
    public List<UserEntity> findUsersByParentId(Integer id)
    {
        return  userService.findByParentId(id);
    }

    public HdfsResourceEntity findHdfsResourceEntityFirstByUrl(String url) {
        return hdfsResourceService.findFirstByUrl(url);
    }
    public HbaseResourceEntity findHbaseResourceEntityBySpaceName(String SpaceName) {
        return hbaseResourceService.findBySpaceName(SpaceName);
    }
    public HiveResourceEntity findHiveResourceEntityBySpaceName(String dataBaseName) {
        return hiveResourceService.findByDatabaseName(dataBaseName);
    }
    public YarnResourceEntity findYarnResourceEntityBySpaceName(String queueName) {
        return yarnResourceService.findFirstByQueueName(queueName);
    }
    public void save(UserEntity userEntity) {
        userService.save(userEntity);
    }
    public UserEntity findUserById(int id) {
        return userService.findUserById(id);
    }

    public void delete(UserEntity userEntity) {
        userService.delete(userEntity);
    }

    public void checkAndAddKerberos(String userName, String passWord) {
        //判断是否开启kerberos模式
        if(clusterConfigUtil.checkKerberized()){
            //1、kerberos 用户？ 存在则删除，然后重新创建
            if (kerberosService.findPrincipalExists(userName)) {
                kerberosService.deletePrincipal(userName);
            }
            //2、创建kerberos用户
            if (!kerberosService.addPrincipal(userName, passWord)) {
                throw new ApiException("KerberosService--save--failed");
            }
        }
        //3、直接增加linux用户（不判断）
//        linuxService.operateUerAndGroupOnLinux(userName, userName, passWord, 1);
        //4、判断range 存在 不操作  不存在 同步
        rangerService.rangerUserAddByHttp(userName, userName);
        //3、直接增加linux用户（不判断） 这个不比较耗时放后面
        linuxService.operateUerAndGroupOnLinux(userName, userName, passWord, 1);
        List<String> hostNameList = clusterConfigUtil.getHostsConfig();
        if(hostNameList!=null && hostNameList.size()>0){
            try {
                Thread.sleep(hostNameList.size()*500);
            } catch (InterruptedException e) {
                logger.error("operateUerAndGroupOnLinux then sleep ,error {}",e);
            }
        }
    }

    public void updatePassword(String oldPd, String newPd, Integer userId, UserEntity loginUser) {
        //只传userId和新密码  则表示修改下级密码
        if (null != userId && StringUtils.isBlank(oldPd)) {
            UserEntity updateUser = findUserById(userId);
            //检查用户是否存在
            if (null == updateUser) {
                throw new ApiException(String.format("%s%d%s","用户",userId,"不存在"));
            }
            //判断是否有权限修改
            if (!updateUser.getParentId().equals(loginUser.getId())) {
                throw new ApiException(String.format("%s%d%s","对",userId,"用户无修改权限"));
            }
            if(clusterConfigUtil.checkKerberized()){
                //修改kerberos密码
                if (!kerberosService.changePrincipalPassword(updateUser.getName(), newPd)) {
                    throw new ApiException("修改kerberos密码失败");
                }
            }
            //修改linux用户密码
            linuxService.changeLinuxUserPassword(updateUser.getName(), newPd);
            //修改数据库信息
            updateUser.setPassword(base64PasswordEncoder.encode(newPd));
            updateUser.setPasswordModifyTime(new Date());
            save(updateUser);
        }//只传旧密码和新密码 表示修改自己密码
        else if (StringUtils.isNotBlank(oldPd) && null == userId) {
            //校验原密码
            if (!base64PasswordEncoder.matches(oldPd, loginUser.getPassword())) {
                throw new ApiException("旧密码输入错误");
            }
            if (oldPd.equals(newPd)) {
                throw new ApiException("新密码和旧密码相同");
            }
            //修改kerberos密码  admin不需要修改kerberos密码
            if (!RoleEnum.Admin.getValue().equals(loginUser.getRole())) {
                if(clusterConfigUtil.checkKerberized()){
                    if (!kerberosService.changePrincipalPassword(loginUser.getName(), newPd)) {
                        throw new ApiException("修改kerberos密码失败");
                    }
                }
                linuxService.changeLinuxUserPassword(loginUser.getName(), newPd);
            }
            loginUser.setPassword(base64PasswordEncoder.encode(newPd));
            loginUser.setPasswordModifyTime(new Date());
            save(loginUser);
        } else {
            throw new ApiException("输入有误");
        }
    }
    //返回创建用户id
    public Integer add(UserAddParam userAddParam, UserEntity userLogin) {
        if (StringUtils.isBlank(userAddParam.getUserName()) || StringUtils.isBlank(userAddParam.getPassword())) {
            throw new ApiException("输入参数不完整");
        }
        UserEntity addUser = findByName(userAddParam.getUserName());
        if (null != addUser) {
            throw new ApiException("该用户已经存在userName:" + userAddParam.getUserName());
        }
        addUser = new UserEntity();
        addUser.setPassword(base64PasswordEncoder.encode(userAddParam.getPassword()));
        addUser.setName(userAddParam.getUserName());
        addUser.setDescription(userAddParam.getDescription());
        addUser.setParentId(userLogin.getId());
        addUser.setRole(RoleEnum.User.getValue());
        if (RoleEnum.Admin.getValue().equals(userLogin.getRole())) {
            addUser.setRole(RoleEnum.Tenant.getValue());
        }
        save(addUser);
        return addUser.getId();
    }
    //根据id删除user
    @Transactional(transactionManager = "transactionManagerDataspace")
    public void deleteUserById(Integer userId) {
        UserEntity deleteUser = findUserById(userId);
        String userName = deleteUser.getName();

        if (clusterConfigUtil.checkKerberized()){
            // 1 删除kerberos
            kerberosService.deletePrincipal(userName);
        }
        // 2 删除linux用户
        linuxService.operateUerAndGroupOnLinux(userName, userName, 2);
        // 3 删除range用户和组
        try {
            rangerService.deleteUserByName(userName);
            rangerService.deleteGroupByName(userName);
        } catch (Exception e) {
            throw new ApiException("delete User or Group filed ");
        }
        userResRelationSerivce.delByUserId(deleteUser.getId());
        delete(deleteUser);
    }
    public OpResult deleteUser(Integer userId, UserEntity userLogin, Integer isDelResource) {
        OpResult result = new OpResult();
        result.setCode(1);
        result.setMsg("删除成功");
        UserEntity deleteUser = findUserById(userId);
        if (null == deleteUser) {
            throw new ApiException("用户不存在" + userId);
        }
        if (!userLogin.getId().equals(deleteUser.getParentId())) {
            throw new ApiException(String.format("%s%d%s","对用户userId:",userId," 无删除权限"));
        }
        //删除租户
        if (RoleEnum.Admin.getValue().equals(userLogin.getRole())) {
            List<UserEntity> deleteUsersByParentId = findUsersByParentId(userId);
            //删除租户下所有用户
            for (UserEntity userEntity : deleteUsersByParentId) {
                deleteUserById(userEntity.getId());
            }
            result = deleteResource(deleteUser, isDelResource);

            deleteUserById(deleteUser.getId());
        }
        //删除用户
        if (RoleEnum.Tenant.getValue().equals(userLogin.getRole())) {
            deleteUserById(deleteUser.getId());
        }
        return result;
    }
    //删除资源
    public OpResult deleteResource(UserEntity deleteUser, Integer isDelResource) {
        OpResult result = new OpResult();
        result.setCode(1);
        String msg = "删除租户成功";
        try {
            YarnResourceEntity byQueueName = yarnResourceService.findFirstByQueueName(deleteUser.getName());
            if(null!=byQueueName){
                yarnManagerService.delRes(byQueueName.getId());
            }
        } catch (Exception a) {

        }
        try {
            KafkaResourceEntity firstByTopicName = kafkaResourceService.findFirstByTopicName(deleteUser.getName());
            if(null!=firstByTopicName){
                kafkaManagerService.delRes(firstByTopicName.getId());
            }
        } catch (Exception e) {

        }
        if (isDelResource == 1) {
            //hdfs
            boolean isHdfsExist = componentDesiredStateService.isComponentExist("HDFS_CLIENT");
            if (isHdfsExist) {
                try {
                    HdfsResourceEntity hdfsResourceEntity = hdfsResourceService.findFirstByUrl(String.format("%s%s%s", TConstants.USRPATH, "/", deleteUser.getName()));
                    if (null != hdfsResourceEntity) {
                        hdfsManagerService.delRes(hdfsResourceEntity.getId(), 0);
                    }
                } catch (Exception a) {
                    msg = msg + ",删除该租户的hdfs资源失败，请去后台手动删除";
                    result.setCode(2);
                }
            }
            //hbase
            boolean isHbaseExist = componentDesiredStateService.isComponentExist("HBASE_MASTER");
            if (isHbaseExist) {
                try {
                    HbaseResourceEntity hbaseResourceEntity = hbaseResourceService.findBySpaceName(deleteUser.getName());
                    if (null != hbaseResourceEntity) {
                        hbaseManagerService.delRes(hbaseResourceEntity.getId(), "", 0);
                    }
                } catch (Exception a) {
                    msg = msg + ",删除该租户的hbase资源失败，请去后台手动删除";
                    result.setCode(2);
                }
            }
            //hive
            boolean isHiveExist = componentDesiredStateService.isComponentExist("HIVE_SERVER");
            if (isHiveExist) {
                try {
                    HiveResourceEntity hiveResourceEntity = hiveResourceService.findByDatabaseName(deleteUser.getName());
                    if (null != hiveResourceEntity) {
                        hiveManagerService.delRes(hiveResourceEntity.getId(), 0);
                    }
                } catch (Exception a) {
                    msg = msg + ",删除该租户的hive资源失败，请去后台手动删除";
                    result.setCode(2);
                }
            }
        }
        result.setMsg(msg);
        return result;
    }

    public UserEntity getUserDetails(UserEntity loginUser, Integer userid) {
        UserEntity getUser = findUserById(userid);
        if (null == getUser) {
            throw new ApiException("该用户不存在:" + userid);
        }
        if (!loginUser.getId().equals(getUser.getParentId())) {
            throw new ApiException("无权限");
        }
        return getUser;
    }
    public void updateUserDescription(EditUserParam editUserParam, UserEntity loginUser) {
        UserEntity userById = findUserById(editUserParam.getUserId());
        if (null == userById) {
            throw new ApiException("该用户不存在userid:" + editUserParam.getUserId());
        }
        if (!loginUser.getId().equals(userById.getParentId())) {
            throw new ApiException("无编辑权限");
        }
        userById.setDescription(editUserParam.getDescription());
        save(userById);
    }
    //用户失败次数更新调度任务
    @Transactional(transactionManager = "transactionManagerDataspace")
    public void updateUserFailureTimes() {
        userService.updateUserFailureTimes();
    }

    //超级管理员次数更新调度任务
    @Transactional(transactionManager = "transactionManagerDataspace")
    public void updateAdminFailureTimes() {
        userService.updateAdminFailureTimes();
    }


    public List<UserEntity> findByFailureTimesGreaterThanEqualAndParentId(Integer failureTimes, Integer parentId) {
        return userService.findByFailureTimesGreaterThanEqualAndParentId(failureTimes, parentId);
    }

    public List<UserEntity> findByFailureTimesGreaterThanEqual(Integer failureTimes) {
        return userService.findByFailureTimesGreaterThanEqual(failureTimes);
    }
    public List<UserEntity> findAll() {
        return userService.findAll();
    }
}


